/*
\ brief:  实现文件
\ author: 清晨与猫鱼
*/
#include <iostream>     // 引入标准输入输出库

/*
\ brief :  抽象接口
\ author : 清晨与猫鱼
*/
class Shape {
public:
    virtual void draw() = 0;        // 虚函数接口
};



/*
\ brief :  长方形
\ author : 清晨与猫鱼
*/
class Rectangle 
    : public Shape {
public:
    void draw() {
        std::cout << "Rectangle" << std::endl;
    }
};


/*
\ brief:  正方形
\ author: 清晨与猫鱼
*/
class Square 
    : public Shape {
public:
    void draw() {
        std::cout << "Square" << std::endl;
    }
};


/*
\ brief :  圆形
\ author : 清晨与猫鱼
*/
class Circle 
    : public Shape {
public:
    void draw() {
         std::cout << "Circle" << std::endl;
    }
};

/*
\ brief :  抽象接口
\ author : 清晨与猫鱼
*/
class Color {
public:
    virtual void fill() = 0;
};

/*
\ brief :  红色
\ author : 清晨与猫鱼
*/
class Red
    : public Color {
public:
    void fill() {
        std::cout << "Red" << std::endl;
    }
};


/*
\ brief :   绿色
\ author : 清晨与猫鱼
*/
class Green 
    : public Color {
public:
    void fill() {
        std::cout << "Green" << std::endl;
    }
};


/*
\ brief :  蓝色
\ author : 清晨与猫鱼
*/
class Blue 
    : public Color {
public:
    void fill() {
        std::cout << "Blue" << std::endl;
    }
};


/*
\ brief :  抽象工厂
\ author : 清晨与猫鱼
*/
class AbstractFactory {
public:  
   virtual Color* getColor(const std::string& ) =0;
   virtual Shape* getShape(const std::string& ) =0;
};


/*
\ brief :  形状工厂
\ author : 清晨与猫鱼
*/
class ShapeFactory
    : public AbstractFactory {
public:
    Shape* getShape(const std::string& shapeType) {
        if (shapeType.empty()) {
            return nullptr;
        }else if (shapeType == "Rectangle") {
            return new Rectangle();
        }else if (shapeType == "Square") {
            return new Square();
        }else if (shapeType == "Circle") {
            return new Circle();
        }
        return nullptr;
    }

    Color* getColor(const std::string& colorType) {
        return nullptr;
    }
    
};


/*
\ brief :  颜色工厂
\ author : 清晨与猫鱼
*/
class ColorFactory 
    : public AbstractFactory {
public:

    Shape* getShape(const std::string& shapeType) {
        return nullptr;
    }

    Color* getColor(const std::string& colorType) {
        if (colorType.empty()) {
            return nullptr;
        }else if (colorType == "Red") {
            return new Red();
        }else if (colorType == "Green") {
            return new Green();
        }else if (colorType == "Blue") {
            return new Blue();
        }
        return nullptr;
    }
};


/*
\ brief :  工厂生成器
\ author : 清晨与猫鱼
*/
class FactoryProducer 
    : public AbstractFactory {
public:

/*
\ brief:  根据条件返回特定的工厂
\ author: 清晨与猫鱼
*/
    static AbstractFactory* getFactory(const std::string& choice) {
        if (choice.empty()) {
            return nullptr;
        }else if (choice == "ShapeFactory") {
            return new ShapeFactory();
        }else if (choice == "ColorFactory") {
            return new ColorFactory();
        }
        return nullptr;
    }
};

